/*
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

package org.geohunter.activity.main;

import com.google.android.maps.MapActivity;

import org.geohunter.GeoFixProvider;
import org.geohunter.GeocacheFactory;
import org.geohunter.GeoFixProviderDI;
import org.geohunter.GraphicsGenerator;import org.geohunter.R;
import org.geohunter.Toaster;
import org.geohunter.activity.cachelist.CacheListTabDI;
import org.geohunter.activity.compass.CompassTabDI;
import org.geohunter.activity.compass.DetailsTabDI;
import org.geohunter.activity.filterlist.FilterTypeCollection;
import org.geohunter.activity.map.MapTab;
import org.geohunter.activity.map.MapTabDI;
import org.geohunter.activity.osmmap.OsmMapTab;
import org.geohunter.activity.osmmap.OsmMapTabDI;
import org.geohunter.activity.sources.SourcesTab;
import org.geohunter.bcaching.BcachingConfig;
import org.geohunter.database.DatabaseLocator;
import org.geohunter.database.DbFrontend;
import org.geohunter.task.TaskQueueRunner;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TabHost;

//MapView can only be used from within a MapActivity, so the main activity
//must be a MapActivity. TabActivity didn't add much functionality anyway.
public class MainActivity extends MapActivity {

    private DbFrontend mDbFrontend;
    private GuiState mGuiState;
    private TabHostWrapper mTabHostWrapper;
    private IntentHandler mIntentHandler;
    private Toaster mSdcardErrorToaster;
    private TaskQueueRunner mBcachingTaskRunner;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mSdcardErrorToaster = new Toaster(this, R.string.toaster_sdcard_error, true);
        
        boolean mounted = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (!mounted) {
            Log.e("geohunter", "External storage in state '" + Environment.getExternalStorageState() + 
                    "': Not starting GeoHunter");
            mSdcardErrorToaster.showToast();
            this.finish();  //Don't start GeoHunter at all
            return;
        }
        
        if (!DatabaseLocator.createStorageDirectory()) {
            mSdcardErrorToaster.showToast();
            this.finish();  //Don't start GeoHunter at all
        }
        
        DatabaseLocator databaseLocator = new DatabaseLocator(this);
        databaseLocator.moveOldDatabase();
        
        LayoutInflater layoutInflater = getLayoutInflater();
        final TabHost tabHost = 
            (TabHost)layoutInflater.inflate(R.layout.tabs, null);
        tabHost.setup();
        setContentView(tabHost);

        GeocacheFactory geocacheFactory = new GeocacheFactory();
        mDbFrontend = new DbFrontend(DatabaseLocator.getDatabasePath(), geocacheFactory);
        final GeoFixProvider geoFixProvider = GeoFixProviderDI.create(this);
        FilterTypeCollection filterTypeCollection = new FilterTypeCollection(this);

        mTabHostWrapper = new TabHostWrapper(tabHost, geoFixProvider);
        mGuiState = new GuiState(mDbFrontend, mTabHostWrapper, filterTypeCollection, 
                geocacheFactory);
        final GraphicsGenerator graphicsGenerator = new GraphicsGenerator(getResources());

        //SourceFactory sourceFactory = geocacheFactory.getSourceFactory();
        final SharedPreferences sharedPreferences = PreferenceManager
          .getDefaultSharedPreferences(this);
        mBcachingTaskRunner = new TaskQueueRunner();
        final BcachingConfig bcachingConfig = 
            new BcachingConfig(sharedPreferences, mBcachingTaskRunner);

        mTabHostWrapper.addTab(CacheListTabDI.create(this, layoutInflater, 
                mGuiState, mDbFrontend, geoFixProvider, geocacheFactory, 
                filterTypeCollection, bcachingConfig, graphicsGenerator));
        MapTab googleMapTab = MapTabDI.create(this, mGuiState, geocacheFactory, 
                mDbFrontend, filterTypeCollection, geoFixProvider, 
                bcachingConfig, graphicsGenerator);
        OsmMapTab osmMapTab = OsmMapTabDI.create(this, mGuiState, geoFixProvider, 
                mDbFrontend, graphicsGenerator, filterTypeCollection);
        mTabHostWrapper.addTab(SwitchableMapTab.create(this, mGuiState, 
                googleMapTab, osmMapTab));
        mTabHostWrapper.addTab(CompassTabDI.create(this, mGuiState, mDbFrontend, 
                geoFixProvider, layoutInflater, graphicsGenerator));
        mTabHostWrapper.addTab(DetailsTabDI.create(this, mGuiState, mDbFrontend, layoutInflater));
        mTabHostWrapper.addTab(SourcesTab.create(this, layoutInflater, 
                mDbFrontend, bcachingConfig, mGuiState, geoFixProvider, 
                geocacheFactory));
        
        mGuiState.onCreate(savedInstanceState);
        mTabHostWrapper.onCreate(savedInstanceState);
        
        mIntentHandler = new IntentHandler(mGuiState, geocacheFactory, mDbFrontend);
        mIntentHandler.handleIntent(getIntent());
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mGuiState.onSaveInstanceState(outState);
    }
    
    @Override
    public void onResume() {
        super.onResume();
        Log.d("geohunter", "MainActivity.onResume()");
        
        boolean mounted = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (!mounted) {
            Log.e("geohunter", "External storage in state '" + Environment.getExternalStorageState() + 
                    "': Not resuming GeoHunter");
            mSdcardErrorToaster.showToast();
            this.finish();  //Don't start GeoHunter at all
            return;
        }
        
        mDbFrontend.openDatabase();
        mTabHostWrapper.onResume();
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        return (mTabHostWrapper.onContextItemSelected(item) 
                || super.onContextItemSelected(item));
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        return true;
        //return mGuiState.onCreateOptionsMenu(menu);
    }

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onMenuOpened(int, android.view.Menu)
     */
    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        super.onMenuOpened(featureId, menu);
        return mTabHostWrapper.onMenuOpened(featureId, menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return mTabHostWrapper.onPrepareOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return (mTabHostWrapper.onOptionsItemSelected(item) 
                || super.onOptionsItemSelected(item));
    }
    
    @Override
    public void onNewIntent (Intent intent) {
        super.onNewIntent(intent);
        Log.d("geohunter", "onNewIntent action=" + intent.getAction() + " data="+intent.getData());
        mIntentHandler.handleIntent(intent);
    }
    
    //Coming back from the Edit screen or camera
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d("geohunter", "MainActivity.onActivityResult()");
        mGuiState.notifyDataViewChanged();
    }
    
    @Override
    public void onPause() {
        super.onPause();
        Log.d("geohunter", "MainActivity.onPause() " + this);
        mBcachingTaskRunner.clearEnqueued();
        mBcachingTaskRunner.abort();
        mTabHostWrapper.onPause();
        mDbFrontend.closeDatabase();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mTabHostWrapper.onKeyDown(keyCode, event))
            return true;
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    @Override
    public void onConfigurationChanged(final Configuration newConfig)
    {
        Log.d("geohunter", "MainActivity.onConfigurationChanged()");
        // Ignore orientation change to keep activity from restarting
        super.onConfigurationChanged(newConfig);
    }
    
    /*
    @Override
    public Object onRetainNonConfigurationInstance() {
        return getIntent();
    }
*/
}
